<template>
  <div class="block">
    <div class="button__group">
      当前设备
      <el-select v-model="curentDevieId" placeholder="请选择">
        <el-option
          v-for="item in devices"
          :key="item.device_id"
          :label="item.device_name || item.device_mac"
          :value="item.device_id">
        </el-option>
      </el-select>
    </div>
    <div class="deviceStatus">
      设备状态：
      <span :class="isOnline ? 'online': 'offline'">{{isOnline ? '在线': '离线'}}</span>
    </div>
    <div class="deviceStatus">
      mqtt连接状态：
      <span :class="mqttConnected ? 'online': 'offline'">{{mqttConnected ? '在线': '离线'}}</span>
    </div>

    <el-table
      class="mt30 table"
      :data="dataPoint"
      border>
      <el-table-column prop="index" label="索引" ></el-table-column>
      <el-table-column  label="端点值" prop="value"></el-table-column>
    </el-table>

    <div class="button__group">
      <el-button type="primary" @click="dialogFormVisible = true"  size="small" class="mt10">单个修改数据端点</el-button>
      <el-button type="primary" @click="dialogDeviceLogs = true"  size="small" class="mt10">显示设备日志</el-button>
    </div>
    
    
    <!-- Form -->
    <el-dialog title="单个修改数据端点" :visible.sync="dialogFormVisible" size="full">
      <el-form :model="form" ref="form" :rules="rules" label-width="">
        <el-form-item label="index" prop="index">
          <el-input v-model="form.index" size="mini"></el-input>
        </el-form-item>
        
        <el-form-item label="类型" prop="type">
          <el-select v-model="form.type" placeholder="请选择类型" style="width:100%;">
            <el-option :label="item.label" :value="item.value" v-for="item in DATAPOINT_TYPES" :key="item.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="value" prop="value">
          <el-input v-model="form.value" size="mini"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false" size="small">取 消</el-button>
        <el-button type="primary" @click="onSubmit" size="small">确 定</el-button>
        
      </div>
    </el-dialog>
    
    <el-dialog title="设备日志" :visible.sync="dialogDeviceLogs" size="full">
      <el-collapse v-model="activeName" accordion  style="text-align:left;">
        <el-collapse-item :title="item.time" :name="index + 1" v-for="(item, index) in logs" :key="item.timestamp">
          <p style="word-wrap:break-word;">{{item.msg}}</p>
        </el-collapse-item>
      </el-collapse>
    </el-dialog>
  </div>
</template>

<script>
import api from '@/api'
import _ from 'lodash'
import XSDK from 'static/xsdk'
const DATAPOINT_TYPES = [
  { value: '1', label: '布尔类型' },
  { value: '2', label: '单字节(无符号)', min: 0, max: 255 },
  { value: '3', label: '16位短整型(有符号)', min: -32768, max: 32767 },
  { value: '4', label: '32位整型(有符号)', min: -2147483648, max: 2147483647 },
  { value: '5', label: '浮点', min: -9223372036854775808, max: 9223372036854775807 },
  { value: '6', label: '字符串' },
  { value: '7', label: '字节数组(暂不支持微信端)' },
  { value: '8', label: '16位短整型(无符号)', min: 0, max: 65535 },
  { value: '9', label: '32位整型(无符号)', min: 0, max: 4294967295 }
]
export default {
  name: 'hello',

  data () {
    return {
      ws: null,
      status: 10,
      curentDevieId: '',
      curentMqtt: {},
      DATAPOINT_TYPES,
      productId: '',
      vDevice: {},
      devices: [],
      devicesEvents: [],
      dataPoint: [],
      dialogFormVisible: false,
      dialogDeviceLogs: false,
      mqttConnected: false,
      noSupportMqtt: false,
      logs: [],
      activeName: '1',
      form: {
        index: '',
        value: '',
        type: ''
      },
      rules: {
        value: [
          { required: true, message: '请输入数据端点的值', trigger: 'blur' }
        ],
        type: [
          { required: true, message: '请选择类型', trigger: 'change' }
        ],
        index: [
          { required: true, message: '请输入数据端点的序号', trigger: 'blur' }
        ]
      }
    }
  },

  computed: {
    isOnline () {
      return this.vDevice.online
    }
  },

  watch: {
    async curentDevieId (val) {
      if (!val) return
      this.dataPoint = []
      let find = _.find(this.devices, {device_id: val})
      if (!find) return
      await this.fetchVDevice(find.device_pid, find.device_id)
      if (!this.vDevice.online) return
      if (this.vDevice.conn_prot === 2) {
        this.noSupportMqtt = false
        if (!this.mqttConnected) {
          await this.initMqtt()
        }
        let curentMqtt = _.find(this.devicesEvents, {id: val})
        if (!curentMqtt) return
        this.curentMqtt = curentMqtt
        this.fetchDatapoint(curentMqtt)
        this.fetchDeviceLogs(curentMqtt)
        this.listenDatapoint(curentMqtt)
      } else {
        this.noSupportMqtt = true
        this.$message.error('当前协议，不支持mqtt')
      }
    }
  },

  beforeDestroy () {
    this.destorySdk()
  },

  mounted () {
    this.fetchDeviceList()
  },

  methods: {
    async fetchDeviceList () {
      // 获取设备列表
      let {data} = await api.fetchDeviceList(window.localStorage.userId)
      this.devices = data.map(item => {
        return {
          device_id: item.id,
          device_name: item.name,
          device_mac: item.mac,
          device_pid: item.product_id
        }
      })
      if (!this.devices.length) return
      this.productId = this.devices[0].device_pid
      this.curentDevieId = this.devices[0].device_id
    },

    // 初始化维保mqtt
    initMqtt () {
      return new Promise((resolve, reject) => {
        this.mqttConnected = false
        let ws = new XSDK('mqtt', {
          type: 'app',
          host: 'wss://mqtt.xlink.cn:443/mqtt',
          userid: window.localStorage.getItem('userId'), // 微信用户在云智易平台的user_id，通过获取OpenID接口获取
          authorize: window.localStorage.getItem('authorize'), // 微信用户在云智易平台的用户认证码，通过获取OpenID接口获取
          keepAliveInterval: 360
        })
        this.ws = ws

        ws.on('ready', () => {
          this.mqttConnected = true
          ws.emit('adddevices',
            this.devices
          )
        })
        .on('devicesready', (devices) => {
          this.devicesEvents = devices
          console.log('设备就绪')
          resolve()
        })
        .on('error', (err) => {
          console.log(err)
          this.ws = null
          this.devicesEvents = []
          this.mqttConnected = false
          reject(err)
        })
      })
    },

    // 获取设备端点值
    fetchDatapoint (socketObj) {
      if (!this.mqttConnected) {
        console.log('设备已经断开')
        return
      }
      socketObj.emit('probe', (res) => {
        console.log(res)
        // {data: [{index: 0, value: 0 ,type: 0}], deviceId: 11}
        if (this.curentDevieId !== res.deviceId) return
        if (res.data) {
          this.dataPoint = res.data
        }
      })
      socketObj.on('error', (err) => {
        console.log(err)
      })
    },

    // 获取设备端点值
    fetchDeviceLogs (socketObj) {
      if (!this.mqttConnected) {
        console.log('设备已经断开')
        return
      }
      socketObj.emit('log', (res) => {
        console.log(res)
        if (res.data) {
          let obj = _.cloneDeep(res.data)
          obj.time = new Date(obj.timestamp).toString()
          this.logs.push(obj)
        }
      })
    },

    // 监听
    listenDatapoint (socketObj) {
      if (!this.mqttConnected) {
        console.log('设备已经断开')
        return
      }
      socketObj.on('data', (res) => {
        console.log(res)
        // {data: [{index: 0, value: 0 ,type: 0}], deviceId: 11, type: 'datapoint}
        if (this.curentDevieId !== res.deviceId) return
        if (res.type === 'datapoint' && res.data.length) {
          let {data} = res
          this.updateDatapoint(data)
        }
      })
    },

    updateDatapoint (data) {
      data.forEach(changData => {
        this.dataPoint.forEach((item, index) => {
          if (item.index === changData.index) {
            this.dataPoint.splice(index, 1, {
              index: changData.index,
              value: changData.value
            })
          }
        })
      })
    },

    // 提交单个数据端点
    onSubmit () {
      if (!this.isOnline) {
        console.log('设备不在线')
        return
      }
      // 应用设置数据端点
      this.$refs.form.validate(valid => {
        if (!valid) return
        let val = this.form.value
        if (val === 'true' || val === 'false') {
          val = val === 'true'
        }
        let data = [{
          index: this.form.index * 1, // 必须整型
          value: val,
          type: this.form.type
        }]
        if (data.some(item => item.type === 0)) {
          return
        }
        console.log(data)

        this.curentMqtt.emit('senddata', { // 发送数据端点数据
          type: 'datapoint',
          data
        }, (res) => {
          console.log(res)
          // {status: 0, msg: "datapoint set successfully"}
          if (res.status === 0) {
            this.$message('发送成功')
            let find = _.find(this.dataPoint, {index: this.form.index - 0})
            if (!find) return
            // 设备不会上报云端需要自动更新
            find.value = this.form.value
          }
        })
        this.dialogFormVisible = false
      })
    },

    destorySdk () {
      if (this.ws) {
        this.ws.emit('destory')
        this.ws = null
        this.devicesEvents = []
        console.log('销毁mqtt')
      }
      this.mqttConnected = false
    },

    refresh () {
      if (this.ws) {
        this.destorySdk()
      }
      this.initMqtt()
    },

    // 获取设备在线信息
    async fetchVDevice (productId, deviceId) {
      let {data} = await api.getVDevice(productId, deviceId)
      this.vDevice = data
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.block {
  width: 600px;
  height: calc(100% - 61px);
  box-sizing: border-box;
  padding: 10px;
  overflow: auto;
}
.table {
  width: 100%;
}
.mt30 {
  margin-top: 30px;
}
.mt10 {
  margin-top:10px; 
}
.button__group {
  padding:10px 0px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: wrap;
}

.online {
  color: green;
}
.offline {
  color: red;
}
</style>
